package gov.pbc.nn.kjgl.fxq.superviseDocument.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import javax.annotation.Resource;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.core.entity.BaseEntity;
import gov.pbc.nn.kjgl.fxq.attachment.AttachmentDao;
import gov.pbc.nn.kjgl.fxq.attachment.AttachmentEntity;
import gov.pbc.nn.kjgl.fxq.superviseDocument.entity.SuperviseDocument;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlan;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlanDept;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlanHeader;

import org.apache.commons.lang.StringUtils;
import org.h2.command.dml.Delete;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.jdbc.core.RowMapper;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.exception.NoneLoginException;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.bdf2.core.service.IDeptService;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.data.variant.Record;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.dorado.uploader.util.ParameterUtils;

@Component
public class SuperviseDocumentPR {
	
	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao pbcnnCoreHibernateDao;
	
	@Resource(name = PbcnnCoreJdbcDao.BEAN_ID)
	private PbcnnCoreJdbcDao jdbcDao;
	
	@Autowired
	@Qualifier(IDeptService.BEAN_ID)
	private IDeptService deptService;
	
	
	

   /*-----------------------DataProvider-----------------------*/
	
	@DataProvider
	public void loadDocument(Page<SuperviseDocument> page, Criteria criteria) {
		IUser user= ContextHolder.getLoginUser();
		if(user==null)
			throw new NoneLoginException("请先登录！");
		if(user.getDepts()==null||user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");
		Dept dept=(Dept) user.getDepts().get(0);
		List<IDept> children= deptService.loadDeptsByParentId(dept.getParentId(), dept.getCompanyId());
		List<String> childrenIds=new ArrayList<String>();
		childrenIds.add(dept.getCDept().getId());
		DetachedCriteria query = this.hibernateDao.buildDetachedCriteria(criteria, SuperviseDocument.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.in("deptId", childrenIds));
		query.addOrder(Order.desc("createDate"));
		this.hibernateDao.pagingQuery(page, query);
	}

	@DataProvider
	public List<AttachmentEntity> loadAttachmentEntity(String id) {
		DetachedCriteria criteria = DetachedCriteria.forClass(AttachmentEntity.class);
		criteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		criteria.add(Restrictions.eq("fxqEntityId", id));
		criteria.addOrder(Order.desc("createDate"));
		List<AttachmentEntity> values = (List<AttachmentEntity>) this.hibernateDao.query(criteria);
		if (!values.isEmpty()) {
			return values;
		}
		return null;
	}
	
	@DataProvider
	public List<Dept> loadFZH() {
		IUser user= ContextHolder.getLoginUser();
		if(user==null)
			throw new NoneLoginException("请先登录！");
		if(user.getDepts()==null||user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");
		Dept dept=(Dept) user.getDepts().get(0);
		
		String pLevel = this.getDeptParentLevelById(dept.getId()).get(0);
		DetachedCriteria criteria = DetachedCriteria.forClass(Dept.class);
		if(pLevel.equals("1") == false)
		{
			System.out.println(pLevel);
			criteria.add(Restrictions.like("id","%"+dept.getParentId()+"%"));
		}

		criteria.add(Restrictions.isNotNull("deptLevel"));
		criteria.add(Restrictions.ge("deptLevel",pLevel));
		criteria.addOrder(Order.asc("deptLevel"));
		List<Dept> values = (List<Dept>) this.pbcnnCoreHibernateDao.query(criteria);
		if (!values.isEmpty()) {
			return values;
		}
		return null;
	}

	
	/*-----------------------DataResolver-----------------------*/
	@Transactional
	@DataResolver
	public void saveAll(Collection<SuperviseDocument> superviseDocuments) throws Exception
	{
		System.out.println("saveAll");

		IUser user= ContextHolder.getLoginUser();
		if(user==null)
			throw new NoneLoginException("请先登录！");
		if(user.getDepts()==null||user.getDepts().isEmpty())
			throw new NoneLoginException("您未设置部门！");
		Dept dept=(Dept) user.getDepts().get(0);
		for (SuperviseDocument superviseDocument : superviseDocuments) {

			if (EntityUtils.getState(superviseDocument).equals(EntityState.NEW)) {
				//organInfor.setCreateDate(new Date());
				superviseDocument.setDeptId(dept.getCDept().getId());
				superviseDocument.setDeptName(dept.getCDept().getName());
				this.hibernateDao.save(superviseDocument);
			} else if (EntityUtils.getState(superviseDocument).equals(EntityState.MODIFIED)) {
				this.hibernateDao.update(superviseDocument);
			} else if (EntityUtils.getState(superviseDocument).equals(EntityState.DELETED)) {
				this.hibernateDao.delete(superviseDocument);
			}
			List<AttachmentEntity> attachments = EntityUtils.getValue(superviseDocument, "attachments");
			if(attachments!=null){
				for (AttachmentEntity attachment : attachments) {
					if (EntityUtils.getState(attachment).equals(EntityState.NEW)) {
						this.hibernateDao.save(attachment);
					} else if (EntityUtils.getState(attachment).equals(EntityState.MODIFIED)) {
						this.hibernateDao.update(attachment);
					} else if (EntityUtils.getState(attachment).equals(EntityState.DELETED)) {
						this.hibernateDao.delete(attachment);
					}
				}
			}
		}

	}
	
	@SuppressWarnings("unchecked")
	@DataProvider
	public List<Record> tj(final Map<String,Object> param) {
		
		return (List<Record>) hibernateDao.doInHibernateSession(new ISessionCallback<Object>(){
	        @Override
	        public List<Record> doInSession(Session session) {
	    		DetachedCriteria criteria = DetachedCriteria.forClass(SuperviseDocument.class);
	    		ProjectionList prolist=Projections.projectionList(); //
	    		SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
	    		String ct = "";

	    		IUser user= ContextHolder.getLoginUser();
	    		if(user==null)
	    			throw new NoneLoginException("请先登录！");
	    		if(user.getDepts()==null||user.getDepts().isEmpty())
	    			throw new NoneLoginException("您未设置部门！");
	    		Dept dept=(Dept) user.getDepts().get(0);
	    		
	    		if(param != null)
	    			
	    		{
	    			if(param.get("createTimeStart") != null)
		    		{
	    				ct = ct + formatter.format(param.get("createTimeStart"))+"-";
		    			criteria.add(Restrictions.ge("createDate", (Date)param.get("createTimeStart")));
		    		}	
		    		if(param.get("createTimeEnd") != null)
		    		{
		    			ct = ct + formatter.format(param.get("createTimeEnd"));
		    			criteria.add(Restrictions.le("createDate", (Date)param.get("createTimeEnd")));
		    		}
		    		if(param.get("method") != null)
		    		{
		    			if(Integer.parseInt((String)param.get("method")) != -1 )
		    			{
			    			criteria.add(Restrictions.eq("method", Integer.parseInt((String)param.get("method"))));
		    			}
		    		}
		    		if(param.get("fzhId") != null)
		    		{
		    			criteria.add(Restrictions.like("deptId", "%"+(String)param.get("fzhId")+"%"));

		    		}
	    		}
	    			String pLevel = getDeptParentLevelById(dept.getId()).get(0);
	    			if(pLevel !=null && pLevel.equals("1") == false)
	    			{
		    			criteria.add(Restrictions.like("deptId", "%"+(String)dept.getParentId()+"%"));
	    			}

	    		criteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
	    		prolist.add(Projections.rowCount());
	    		prolist.add(Projections.groupProperty("deptId"));
	    		prolist.add(Projections.groupProperty("method"));

	    		criteria.setProjection(prolist);
	    		List <Object[]> ll = criteria.getExecutableCriteria(session).list();
	    		
	    		prolist.add(Projections.groupProperty("industryType"));
	    		criteria.setProjection(prolist);
	    		List <Object[]> llIndustryType = criteria.getExecutableCriteria(session).list();

	    		List<Record> lr = new ArrayList<Record>();
	    		for (Object[] d : ll)
	    		{   
	    			Record r = new Record();
		    		for (Object[] it : llIndustryType)
		    		{  
		    			if(d[1].equals(it[1]) && d[2].equals(it[2]))
		    			{
		    				switch((int)it[3]){
		    				case 10:
		    	    			r.setLong("yhy", (long)it[0]);
		    				    break;
		    				case 11:
		    	    			r.setLong("yhyfr", (long)it[0]);
		    				    break;
		    				case 20:
		    	    			r.setLong("zqqhy", (long)it[0]);
		    				    break;
		    				case 21:
		    	    			r.setLong("zqqhyfr", (long)it[0]);	
		    				    break;
		    				case 30:
		    	    			r.setLong("bxy", (long)it[0]);
		    				    break;
		    				case 31:
		    	    			r.setLong("bxyfr", (long)it[0]);
		    				case 40:
		    	    			r.setLong("zf", (long) it[0]);
		    				case 41:
		    	    			r.setLong("zffr",(long)it[0]);
		    				    break;
		    				}
		    			}
		    		}
	    			String times = d[0].toString();
	    			String deptId = d[1].toString();
	    			int method = (int)d[2];
	    			r.setString("times", times);
	    			r.setString("fzhName", deptService.loadDeptById(deptId).getName());
	    			r.setInt("method", method);
	    			r.setString("createTime", ct);

	    			lr.add(r);
	    		}
				return lr;
	        }
	    });
	}
	public List<String> getDeptParentLevelById(String deptId)
	{
		String deptParentId = deptService.loadDeptById(deptId).getParentId();
		String sql = "select t_dept.dept_level_ as deptLevel from t_dept where id_ = ?";

		return jdbcDao.getJdbcTemplate().query(sql, new Object[] { deptParentId }, new RowMapper<String>() {

			@Override
			public String mapRow(ResultSet resultSet, int arg1) throws SQLException {
				// TODO Auto-generated method stub

				return resultSet.getString("deptLevel");
			}

		});
	}
}	
